<template>
  <el-container style="width: 100%; height: 100%">
    <el-header style="background: #f5f5f5; display: flex; height: 40px; border: 1px solid #e8e8e8; align-items: center">
      <div class="upload-icon" @click="uploadFile">
        <div class="upload-icon">打开OFD</div>
        <el-icon><UploadFilled /></el-icon>
        <input type="file" ref="file" class="hidden" accept=".ofd" @change="fileChanged" />
      </div>
      <div style="display: flex; align-items: center">
        <div class="scale-icon" style="margin-left: 10px" @click="plus">
          <el-icon><ZoomIn /></el-icon>
        </div>
        <div class="scale-icon" @click="minus">
          <el-icon><ZoomOut /></el-icon>
        </div>
        <div class="scale-icon">
          <el-icon @click="firstPage"><ArrowLeftBold /></el-icon>
        </div>

        <div class="scale-icon" style="font-size: 18px" @click="prePage">
          <el-icon><CaretLeft /></el-icon>
        </div>

        <div class="scale-icon">{{ pageIndex }}/{{ pageCount }}</div>

        <div class="scale-icon" style="font-size: 18px" @click="nextPage">
          <el-icon><CaretRight /></el-icon>
        </div>

        <div class="scale-icon" @click="lastPage">
          <el-icon><ArrowRightBold /></el-icon>
        </div>
      </div>
      <div class="upload-icon" @click="printFile">
        <div class="upload-icon">打印OFD</div>
        <el-icon><Printer /></el-icon>
      </div>
    </el-header>
    <el-main style="height: auto; background: #808080; padding: 0" v-loading.fullscreen.lock="loading">
      <div class="main-section" id="content" ref="contentDiv" @mousewheel="scrool"></div>
    </el-main>

    <el-dialog v-model="dialogTableVisible" title="签章信息" draggable>
      <div class="SealContainer-layout">
        <div class="SealContainer-content">
          <p class="content-title">签章信息</p>
          <div class="subcontent">
            <span class="title">签章人</span>
            <span class="value" id="spSigner">[无效的签章结构]</span>
          </div>
          <div class="subcontent">
            <span class="title">签章提供者</span>
            <span class="value" id="spProvider">[无效的签章结构]</span>
          </div>
          <div class="subcontent">
            <span class="title">原文摘要值</span>
            <span class="value" id="spHashedValue" @click="showMore('原文摘要值', 'spHashedValue')" style="cursor: pointer"
              >[无效的签章结构]</span
            >
          </div>
          <div class="subcontent">
            <span class="title">签名值</span>
            <span class="value" id="spSignedValue" @click="showMore('签名值', 'spSignedValue')" style="cursor: pointer"
              >[无效的签章结构]</span
            >
          </div>
          <div class="subcontent">
            <span class="title">签名算法</span>
            <span class="value" id="spSignMethod">[无效的签章结构]</span>
          </div>
          <div class="subcontent">
            <span class="title">版本号</span>
            <span class="value" id="spVersion">[无效的签章结构]</span>
          </div>
          <div class="subcontent">
            <span class="title">验签结果</span>
            <span class="value" id="VerifyRet">[无效的签章结构]</span>
          </div>

          <p class="content-title">印章信息</p>
          <div class="subcontent">
            <span class="title">印章标识</span>
            <span class="value" id="spSealID">[无效的签章结构]</span>
          </div>
          <div class="subcontent">
            <span class="title">印章名称</span>
            <span class="value" id="spSealName">[无效的签章结构]</span>
          </div>
          <div class="subcontent">
            <span class="title">印章类型</span>
            <span class="value" id="spSealType">[无效的签章结构]</span>
          </div>
          <div class="subcontent">
            <span class="title">有效时间</span>
            <span class="value" id="spSealAuthTime">[无效的签章结构]</span>
          </div>
          <div class="subcontent">
            <span class="title">制章日期</span>
            <span class="value" id="spSealMakeTime">[无效的签章结构]</span>
          </div>
          <div class="subcontent">
            <span class="title">印章版本</span>
            <span class="value" id="spSealVersion">[无效的签章结构]</span>
          </div>
        </div>
      </div>
    </el-dialog>
    <el-dialog :title="dialogFormTitle" v-model="dialogFormVisible">
      <span style="text-align: left">
        {{ value }}
      </span>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogFormVisible = false">确 定</el-button>
        </span>
      </template>
    </el-dialog>
  </el-container>
</template>

<script>
import { parseOfdDocument, renderOfd, renderOfdByScale, digestCheck, getPageScale, setPageScale } from "ofd.js";
// import * as JSZipUtils from "jszip-utils";
import printJS from "print-js";

export default {
  name: "",
  props: {
    url: {
      type: String,
      default: () => {
        return "";
      }
    },
    title: {
      type: String,
      default: () => {
        return "";
      }
    }
  },
  data() {
    return {
      ofdBase64: null,
      loading: false,
      pageIndex: 1,
      pageCount: 0,
      scale: 0,
      value: null,
      ofdObj: null,
      screenWidth: document.body.clientWidth,
      dialogTableVisible: false,
      dialogFormVisible: false,
      dialogFormTitle: null
    };
  },

  created() {
    this.file = null;
    this.getOfdDocumentObj(this.url, this.screenWidth);
  },
  mounted() {
    // eslint-disable-next-line @typescript-eslint/no-this-alias
    let that = this;
    this.$refs.contentDiv.addEventListener("scroll", this.scrool);
    window.onresize = () => {
      return (() => {
        that.screenWidth = document.body.clientWidth - 88;
        const divs = renderOfd(that.screenWidth, that.ofdObj);
        that.displayOfdDiv(divs);
      })();
    };
  },

  methods: {
    scrool() {
      let scrolled = this.$refs.contentDiv.firstElementChild?.getBoundingClientRect()?.top - 60;
      let top = 0;
      let index = 0;
      for (let i = 0; i < this.$refs.contentDiv.childElementCount; i++) {
        top +=
          Math.abs(this.$refs.contentDiv.children.item(i)?.style.height.replace("px", "")) +
          Math.abs(this.$refs.contentDiv.children.item(i)?.style.marginBottom.replace("px", ""));
        if (Math.abs(scrolled) < top) {
          index = i;
          break;
        }
      }
      this.pageIndex = index + 1;
    },
    showMore(title, id) {
      this.dialogFormVisible = true;
      this.value = document.getElementById(id).innerText;
      this.dialogFormTitle = title;
    },
    // 放大
    plus() {
      setPageScale(++this.scale);
      const divs = renderOfdByScale(this.ofdObj);
      this.displayOfdDiv(divs);
    },
    // 缩小
    minus() {
      setPageScale(--this.scale);
      const divs = renderOfdByScale(this.ofdObj);
      this.displayOfdDiv(divs);
    },
    // 上一页
    prePage() {
      let contentDiv = document.getElementById("content");
      let ele = contentDiv.children.item(this.pageIndex - 2);
      ele?.scrollIntoView(true);
      ele ? (this.pageIndex = this.pageIndex - 1) : "";
    },
    // 首页
    firstPage() {
      let contentDiv = document.getElementById("content");
      let ele = contentDiv.firstElementChild;
      ele?.scrollIntoView(true);
      ele ? (this.pageIndex = 1) : "";
    },
    // 下一页
    nextPage() {
      let contentDiv = document.getElementById("content");
      let ele = contentDiv.children.item(this.pageIndex);
      ele?.scrollIntoView(true);
      ele ? ++this.pageIndex : "";
    },
    // 尾页
    lastPage() {
      let contentDiv = document.getElementById("content");
      let ele = contentDiv.lastElementChild;
      ele?.scrollIntoView(true);
      ele ? (this.pageIndex = contentDiv.childElementCount) : "";
    },
    // 上传文件
    uploadFile() {
      this.file = null;
      this.$refs.file.click();
    },

    fileChanged() {
      this.file = this.$refs.file.files[0];
      let ext = this.file.name.replace(/.+\./, "");
      if (["ofd"].indexOf(ext) === -1) {
        this.$alert("error", "仅支持ofd类型", {
          confirmButtonText: "确定",
          callback: action => {
            this.$message({
              type: "info",
              message: `action: ${action}`
            });
          }
        });
        return;
      }
      if (this.file.size > 100 * 1024 * 1024) {
        this.$alert("error", "文件大小需 < 100M", {
          confirmButtonText: "确定",
          callback: action => {
            this.$message({
              type: "info",
              message: `action: ${action}`
            });
          }
        });
        return;
      }
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      let that = this;
      let reader = new FileReader();
      reader.readAsDataURL(this.file);
      reader.onload = function (e) {
        that.ofdBase64 = e.target.result.split(",")[1];
      };
      this.getOfdDocumentObj(this.file, this.screenWidth);
      this.$refs.file.value = null;
    },
    // 渲染ofd
    getOfdDocumentObj(file, screenWidth) {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      let that = this;
      let t = new Date().getTime();
      this.loading = true;
      parseOfdDocument({
        ofd: file,
        success(res) {
          console.log(res);
          let t1 = new Date().getTime();
          console.log("解析ofd", t1 - t);
          that.ofdObj = res[0];
          that.pageCount = res[0].pages.length;
          const divs = renderOfd(screenWidth, res[0]);
          let t2 = new Date().getTime();
          console.log("xml转svg", t2 - t1);
          that.displayOfdDiv(divs);
          let t3 = new Date().getTime();
          console.log("svg渲染到页面", t3 - t2);
          that.loading = false;
        },
        fail(error) {
          console.log(error);
          that.loading = false;
          that.$alert("OFD打开失败", error, {
            confirmButtonText: "确定",
            callback: action => {
              this.$message({
                type: "info",
                message: `action: ${action}`
              });
            }
          });
        }
      });
    },

    displayOfdDiv(divs) {
      this.scale = getPageScale();
      let contentDiv = document.getElementById("content");
      contentDiv.innerHTML = "";
      for (const div of divs) {
        contentDiv.appendChild(div);
      }
      if (!this.ofdObj.document["#text"]) {
        const text = document.getElementsByTagName("text");
        for (let i = 0; i < text.length; i++) {
          text[i].style.fillOpacity = 0;
        }
      }
      for (let ele of document.getElementsByName("seal_img_div")) {
        this.addEventOnSealDiv(ele, JSON.parse(ele.dataset.sesSignature), JSON.parse(ele.dataset.signedInfo));
      }
    },
    addEventOnSealDiv(div, SES_Signature, signedInfo) {
      window.HashRet = null;
      window.VerifyRet = signedInfo.VerifyRet;
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      const this_ = this;
      div.addEventListener("click", function () {
        this_.dialogTableVisible = true;
        this_.$nextTick(() => {
          if (SES_Signature.realVersion < 4) {
            document.getElementById("spSigner").innerText = SES_Signature.toSign.eseal.cert.commonName.str;
            document.getElementById("spProvider").innerText = signedInfo.Provider["@_ProviderName"];
            document.getElementById("spHashedValue").innerText = SES_Signature.toSign.dataHash.replace(/\n/g, "");
            document.getElementById("spSignedValue").innerText = SES_Signature.signature.replace(/\n/g, "");
            document.getElementById("spSignMethod").innerText = SES_Signature.toSign.signatureAlgorithm.replace(/\n/g, "");
            document.getElementById("spSealID").innerText = SES_Signature.toSign.eseal.esealInfo.esID.str;
            document.getElementById("spSealName").innerText = SES_Signature.toSign.eseal.esealInfo.property.name.str;
            document.getElementById("spSealType").innerText = SES_Signature.toSign.eseal.esealInfo.property.type;
            document.getElementById("spSealAuthTime").innerText =
              "从 " +
              SES_Signature.toSign.eseal.esealInfo.property.validStart +
              " 到 " +
              SES_Signature.toSign.eseal.esealInfo.property.validEnd;
            document.getElementById("spSealMakeTime").innerText = SES_Signature.toSign.eseal.esealInfo.property.createDate;
            document.getElementById("spSealVersion").innerText = SES_Signature.toSign.eseal.esealInfo.header.version;
          } else {
            document.getElementById("spSigner").innerText = SES_Signature.toSign.eseal.cert.commonName.str;
            document.getElementById("spProvider").innerText = signedInfo.Provider["@_ProviderName"];
            document.getElementById("spHashedValue").innerText = SES_Signature.toSign.dataHash.replace(/\n/g, "");
            document.getElementById("spSignedValue").innerText = SES_Signature.signature.replace(/\n/g, "");
            document.getElementById("spSignMethod").innerText = SES_Signature.signatureAlgID.replace(/\n/g, "");
            document.getElementById("spSealID").innerText = SES_Signature.toSign.eseal.esealInfo.esID.str;
            document.getElementById("spSealName").innerText = SES_Signature.toSign.eseal.esealInfo.property.name.str;
            document.getElementById("spSealType").innerText = SES_Signature.toSign.eseal.esealInfo.property.type;
            document.getElementById("spSealAuthTime").innerText =
              "从 " +
              SES_Signature.toSign.eseal.esealInfo.property.validStart +
              " 到 " +
              SES_Signature.toSign.eseal.esealInfo.property.validEnd;
            document.getElementById("spSealMakeTime").innerText = SES_Signature.toSign.eseal.esealInfo.property.createDate;
            document.getElementById("spSealVersion").innerText = SES_Signature.toSign.eseal.esealInfo.header.version;
          }
          document.getElementById("spVersion").innerText = SES_Signature.toSign.version;
          document.getElementById("VerifyRet").innerText =
            "文件摘要值后台验证中，请稍等... " + (window.VerifyRet ? "签名值验证成功" : "签名值验证失败");
          if (window.HashRet == null || window.HashRet == undefined || Object.keys(window.HashRet).length <= 0) {
            setTimeout(function () {
              const signRetStr = window.VerifyRet ? "签名值验证成功" : "签名值验证失败";
              window.HashRet = digestCheck(window.toBeChecked.get(signedInfo.signatureID));
              const hashRetStr = window.HashRet ? "文件摘要值验证成功" : "文件摘要值验证失败";
              document.getElementById("VerifyRet").innerText = hashRetStr + " " + signRetStr;
            }, 1000);
          }
        });
      });
    },
    // 打印
    printFile() {
      printJS({
        printable: document.getElementById("content"),
        type: "html",
        scanStyles: false,
        // 继承原来的所有样式
        targetStyles: ["*"],
        // headerStyle: "font-weight:800;text-align:center;",
        style: "@page {margin: 0 auto};" // 不打印页眉和页脚
        // honorColor: true // 是否打印彩色文本
      });
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.upload-icon {
  display: flex;
  cursor: pointer;
  justify-content: center;
  align-items: center;
  height: 28px;
  padding-left: 10px;
  padding-right: 10px;
  background-color: rgb(59, 95, 232);
  border-radius: 1px;
  border-color: #5867dd;
  font-weight: 500;
  font-size: 12px;
  color: white;
  margin: 1px;
}

.scale-icon {
  display: flex;
  cursor: pointer;
  justify-content: center;
  align-items: center;
  width: 33px;
  height: 28px;
  background-color: #f5f5f5;
  border-radius: 1px;
  font-weight: 500;
  font-size: 12px;
  color: #333333;
  text-align: center;
  padding: 2px;
}
.scale-icon :active {
  color: rgb(59, 95, 232);
}
.scale-icon :hover {
  color: rgb(59, 95, 232);
}

.text-icon {
  display: flex;
  cursor: pointer;
  justify-content: center;
  align-items: center;
  height: 28px;
  width: 90%;
  background-color: rgb(59, 95, 232);
  border-radius: 1px;
  border-color: #5867dd;
  font-weight: 500;
  font-size: 10px;
  color: white;
  margin-top: 20px;
}

.hidden {
  display: none !important;
}

.SealContainer {
  z-index: 9999;
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
}

.SealContainer .mask {
  background: #000000;
  opacity: 0.3;
}

.content-title {
  font-size: 16px;
  text-align: center;
  border-bottom: 1px solid rgb(59, 95, 232);
  color: rgb(59, 95, 232);
  margin-top: 10px;
}
.SealContainer-content {
  position: relative;
  width: 100%;
  height: 100%;
  overflow-y: auto;
  background: white;
  display: flex;
  flex-direction: column;
  padding: 10px;
  align-items: center;
}

.SealContainer-layout {
  position: relative;
  width: 100%;
  height: 100%;
  overflow-y: auto;
  background: white;
  z-index: 100;
  display: flex;
  flex-direction: column;
  padding: 10px;
  align-items: center;
}

.subcontent {
  width: 80%;
  display: flex;
  flex-direction: column;
  text-align: left;
  margin-bottom: 10px;
  font-family: simsun;
}

.subcontent .title {
  font-weight: 600;
}

.subcontent .value {
  font-weight: 400;
  -webkit-line-clamp: 1;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.main-section {
  /* height: 100%; */
  padding-top: 20px;
  margin-left: 88px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: #808080;
  overflow: hidden;
}

@media (max-width: 767px) {
  .SealContainer-layout {
    position: relative;
    width: 90%;
    height: 90vh;
    overflow-y: auto;
    background: white;
    z-index: 100;
    display: flex;
    flex-direction: column;
    padding: 10px;
    align-items: center;
  }

  .subcontent {
    width: 95%;
    display: flex;
    flex-direction: column;
    text-align: left;
    margin-bottom: 10px;
    font-family: simsun;
  }

  .main-section {
    /* height: calc(100% - 20px); */
    padding-top: 20px;
    margin-left: 0px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: #808080;
    overflow: hidden;
  }
}
</style>
